了解樣板跟資料之後,就可以來了解指令的部分。Vue 可以透過在 HTML 中以被稱為指令的特殊屬性來編寫。可以依據我們提供的資料作不同的處理。
直接將 data 內屬性的資料解析為純文本,僅提供 data 內數據不提供輸出 HTML(如:<span>
)因為 v-text
的內容是在被渲染的時候才解析。
<div id="app"><!-- 樣板 templates -->
<p>歡迎來到{{ shopName }}!雙大括號插值版本</p>
<p>歡迎來到<span v-text="shopName"></span>!指令 v-text 版本</p>
</div>
let vm = new Vue({
el:'#app',
data:{
shopName: '友好商店',
}
})
與 v-text 效果類似,但可以輸出 HTML 代碼。但因為用變數將 HTML 寫入網頁可能會產生 XSS 攻擊的風險,所以只能在信任的資料上運用 v-html。
<div id="app"><!-- 樣板 templates -->
<p>歡迎來到{{ shopName }}!雙大括號插值版本</p>
<p>歡迎來到<span v-text="shopName"></span>!指令 v-text 版本</p>
<p>歡迎來到<span v-html="shopName"></span>!指令 v-html 版本</p>
</div>
let vm = new Vue({
el:'#app',
data:{
shopName: '<span style="color:red;">友好商店</span>',
}
})
屬性 | 解析為純文本 | 頁面加載時或 javascript 出錯 | 動態輸出 HTML |
---|---|---|---|
插值 | 是 | 會呈現{{ 雙大括號 }} | 不行 |
v-text | 是 | 不會 | 不行 |
v-html | 輸出為 html | 不會 | 可以(請謹慎使用) |
有很多方法可以迴避 v-html
的使用,避免在用戶可以操作與提交資訊的網頁中被 XSS 攻擊。單論動態改變字體顏色,v-bind
可以提供我們需要的效果。v-bind
的效果是提供 HTML 屬性,讓我們可以依據條件與情形動態操作該 HTML 標籤下的屬性細節。如:div
區塊內的文字樣式style
,img
內的圖片連結src
等等。
<div id="app">
<p>歡迎來到<span v-html="shopName_00"></span>!指令 v-html 版本</p>
<p>歡迎來到<span v-bind:style="isRed" v-text="shopName_01"></span>!指令 v-bind:style + v-text 版本</p>
</div>
let vm = new Vue({
el:'#app',
data:{
shopName_00: '<span style="color:red;">友好商店</span>',
shopName_01: '友好商店',
isRed: {color: 'red'}
}
})
如範例中,v-bind
後方指定需要調整的屬性,並賦予"isRed"的 data
物件,物件內寫明color:'red'
,即可透過 v-text
與 v-bind:style
達到與 v-html
一樣的紅色文字效果。
如果希望做到 javascript 與 css 分家,v-bind:class
可以幫忙。
<div id="app">
<p>歡迎來到<span v-bind:style="isRed" v-text="shopName_01"></span>!指令 v-bind:style + v-text 版本</p>
<p>歡迎來到<span v-bind:class="classIsRed" v-text="shopName_01"></span>!指令 v-bind:class + v-text 版本</p>
</div>
.redWord { color: red; }
let vm = new Vue({
el:'#app',
data:{
shopName_01: '友好商店',
isRed: {
color: 'red',
},
classIsRed: 'redWord',
}
})
v-bind:class
指定資料內屬性,屬性的值再導向 css 裡對應的 class 屬性。當想綁定兩個以上的 class 時,可以在v-bind:class
後方寫陣列。
<div id="app">
<p>歡迎來到<span v-bind:class="[classIsRed, classIsBold]" v-text="shopName_01"></span>!指令 v-bind:class + v-text 多個樣式版本</p>
</div>
.redWord { color: red; }
.boldWord { font-weight:bold; }
let vm = new Vue({
el:'#app',
data:{
shopName_01: '友好商店',
classIsRed: 'redWord',
classIsBold: 'boldWord'
}
})
v-bind:class
除了字串、陣列,也可以物件來編寫。
<div id="app">
<p>歡迎來到<span v-bind:class="{redWord: true, boldWord: true}" v-text="shopName_01"></span>!指令 v-bind:class + v-text 物件版本 1</p>
</div>
.redWord { color: red; }
.boldWord { font-weight:bold; }
大括號內,冒號的前方是class
名,冒號的後方為布林值 true
/ false
。當布林值為 true
時, class 才會被啟用,才會去 css 裡找對應的class
樣式。但是這種寫法不需要、也無法使用 Vue 實體來控制。為了將來可以做到動態切換 class
,我們應該讓樣式表是可以受到 Vue 實體來操控的。
<div id="app">
<p>歡迎來到<span v-bind:class="{redWord: isItRed, boldWord: IsitBold}" v-text="shopName_01"></span>!指令 v-bind:class + v-text 物件版本 2</p>
</div>
.redWord { color: red; }
.boldWord { font-weight:bold; }
let vm = new Vue({
el:'#app',
data:{
shopName_01: '友好商店',
isItRed: true,
IsitBold: true
}
})
另外,如果認為可閱讀性太差,也可以將 HTML 內的物件中的樣式打包起來,在 Vue 的 data 中作為屬性來存取。
<div id="app">
<p>歡迎來到<span v-bind:class="caution" v-text="shopName_01"></span>!指令 v-bind:class + v-text 物件版本 3</p>
</div>
.redWord { color: red; }
.boldWord { font-weight:bold; }
let vm = new Vue({
el:'#app',
data:{
shopName_01: '友好商店',
caution: {
redWord: true,
boldWord: true
}
}
})
讓 v-bind:class
賦予 caution 的值追蹤到 Vue 實體的 caution 物件,依據 caution 物件裡的 class 名與布林值確認是否套用該同名 css 樣式。同時日後也可以依據條件與情形來動態更改 data 裡的值。
今天的程式碼在這個 codepen 裡,此文諸多不周到的地方還請多包涵指教。
感謝分享
補充 new Vue() 是 Vue 2 語法,
Vue 3 用 Vue.createApp() 取代 new Vue()
https://book.vue.tw/appendix/migration.html#%E5%85%83%E4%BB%B6%E5%AF%A6%E9%AB%94%E5%BB%BA%E7%AB%8B
Vue 2 support will end on Dec 31, 2023. Learn more about Vue 2 Extended LTS.
The Benefits of the New Vue 3 App Initialization Code